package com.gxa.saas.sso.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxa.saas.core.entity.vo.luoj.UserVO;
import com.gxa.saas.core.exception.BusinessException;
import com.gxa.saas.core.exception.ExceptionCode;
import com.gxa.saas.sso.mapper.UserMapper;
import com.gxa.saas.sso.service.UserService;
import com.gxa.saas.sso.util.HttpUtil;
import com.gxa.saas.sso.util.JwtUtil;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotEmpty;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/*
 * @Transactional 处理持久层事务，还能在redis操作时关闭连接
 * */

@Service
@Transactional(rollbackFor = Throwable.class)
@Validated
public class UserServiceImpl extends ServiceImpl<UserMapper, UserVO> implements UserService {

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Resource
    private UserMapper userMapper;

    @Resource
    HttpServletRequest request;

    private static final String SALT = "OnePol:";

    @Override
    public String login(@Validated @NotEmpty(message = "手机号不能为空") String phone,
                     @Validated @NotEmpty(message = "验证码不能为空") String check) throws Exception {
        Object redisCode = redisTemplate.opsForValue().get(SmsServiceImpl.LOGIN_SMS + phone);

        //验证码失效的判断,如果为空则抛出异常
        if(StringUtils.isEmpty(redisCode)){
            throw new BusinessException(ExceptionCode.EXPIRE_CODE);
        }

        //对验证码做校验, 如果不一致则抛出异常
        if(!check.equals(redisCode)){
            throw new BusinessException(ExceptionCode.WRONG_CODE);
        }
        //校验完成，删除验证码
        redisTemplate.delete(SmsServiceImpl.LOGIN_SMS+phone);

        //校验完成，从mysql数据库中查找用户信息

        UserVO user = userMapper.selectOne(new QueryWrapper<UserVO>().eq("phone", phone));

        //如果用户不存在, 则匿名注册,匿名格式: "用户:"+phone , 并指定用户状态
        if(user==null){
            //创建一个User的实例
            user = new UserVO();
            //给当前实例添加状态信息
            //user_status
            user.setIsDel("0");
            //创建一个临时用户name
            user.setUsername("user"+phone);
            //手机号
            user.setPhone(phone);
        }

        if(!user.getIsDel().equals("0")){
            throw new BusinessException(ExceptionCode.WRONG_USER_STATUS);
        }

        //创建时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(new Date());
        user.setCreationTime(LocalDateTime.parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        //user_status
        user.setUserStatus(0);

        //Jwt生成的token
        String token = JwtUtil.sign(phone, check);
        if (user.getToken()!=null){
            redisTemplate.delete(SALT+user.getToken());
        }
        user.setToken(token);
        this.saveOrUpdate(user);
        ObjectMapper objectMapper = new ObjectMapper();
        String value = objectMapper.writeValueAsString(user);

        redisTemplate.opsForValue().set(SALT+token,value,2 ,TimeUnit.HOURS);
        return token;
    }

    @Override
    public UserVO checkWithToken(@Validated @NotEmpty(message = "token不能为空")String token) throws Exception {
        //从redis中获取用户的信息
        String key = SALT+token;
        BoundValueOperations<String, Object> stringOps = redisTemplate.boundValueOps(key);

        Object redisToken = stringOps.get();
        if(StringUtils.isEmpty(redisToken)){
            throw new BusinessException(ExceptionCode.WRONG_TOKEN);
        }

        stringOps.expire(2,TimeUnit.HOURS);
        //使用jackson将token保存的用户json数据转换为User对象并返回
        ObjectMapper objectMapper = new ObjectMapper();
        UserVO user = objectMapper.readValue(redisToken.toString(), UserVO.class);
        return user;
    }

    @Override
    public UserVO userInfo(@NotEmpty(message = "手机号不能为空") String phone) {
        UserVO user = userMapper.selectOne(new QueryWrapper<UserVO>().eq("phone", phone));
        return user;
    }

//    @Override
//    public String getSessionId(@NotEmpty(message = "code不能为空") String code) {
//        String AppId = "wxf73feb267ae2a29f";
//        String AppSecret = "075be73f42245d1fe7ac14a74ba0b788";
//        String url = "https://api.weixin.qq.com/sns/jscode2session?" +
//                "appid=" + AppId +
//                "&secret=" + AppSecret +
//                "&js_code=" + code +
//                "&grant_type=authorization_code";
//        String value = HttpUtil.get(url,null);
//        String uuid = UUID.randomUUID().toString();
//        redisTemplate.opsForValue().set(SALT+uuid,value,30,TimeUnit.MINUTES);
//        return uuid;
//    }

}
